﻿#include "JistDocumentHandler.h"
#include <QAction>
//#include "JistDocument.h"
#include "../documentmanager.h"
#include "../libtiled/objectgroup.h"
#include "../libtiled/mapobject.h"
#include "../mapscene.h"
#include "../addremovemapobject.h"

JistDocumentHandler *JistDocumentHandler::m_pInstance;
JistDocumentHandler::JistDocumentHandler(QObject *parent, JistDocument* doc) :
    QObject(parent),
    m_pDocument(doc)

{
    Q_ASSERT(!m_pInstance);
    m_pInstance = this;
    //QTextCodec * codec = QTextCodec::codecForName("EUC-KR");
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");

    QString localeStr = codec->toUnicode("이미지 추가(&I)");

    mActionAddImage = setAction("이미지 추가(&I)",SIGNAL(triggered()), m_pDocument, SLOT(OpenImage()));
    mActionDeleteImage = setAction("이미지 제거(&D)",SIGNAL(triggered()), m_pDocument->m_ImageTableWidget, SLOT(deleteImage()));
    mActionFakeBmp = setAction("FakeBMP 생성(&I)",SIGNAL(triggered()), m_pDocument->m_ImageTableWidget, SLOT(createFakeBmp()));
    mActionSetImgName = setAction("이름 바꾸기(&N)",SIGNAL(triggered()), m_pDocument->m_ImageTableWidget, SLOT(setName()));
    mActionMoveImgUp = setAction("위로", SIGNAL(triggered()), m_pDocument->m_ImageTableWidget, SLOT(moveItemUp()));
    mActionMoveImgUp->setIcon(QIcon(QLatin1String(":/images/16x16/go-up.png")));
    mActionMoveImgDown = setAction("아래로", SIGNAL(triggered()), m_pDocument->m_ImageTableWidget, SLOT(moveItemDown()));
    mActionMoveImgDown->setIcon(QIcon(QLatin1String(":/images/16x16/go-down.png")));

    mActionAddAnimation = setAction("애니메이션 추가(&A)",SIGNAL(triggered()), this, SLOT(addAnimation()));

    mActionAddScene = setAction("신 추가(&S)", SIGNAL(triggered()), this, SLOT(addScene()));

    mActionAddCell = setAction("셀 추가(&C)", SIGNAL(triggered()), this, SLOT(addCell()));
    mActionSetUIOptCut_WW = setAction("폭늘이기", SIGNAL(triggered()), m_pDocument->m_SpriteTableWidget, SLOT(setOptCut_WW()));
    mActionSetUIOptCut_WW->setIcon(QIcon(QLatin1String(":/images/24x24/widen_w.png")));
    mActionSetUIOptCut_WH = setAction("높이늘이기", SIGNAL(triggered()), m_pDocument->m_SpriteTableWidget, SLOT(setOptCut_WH()));
    mActionSetUIOptCut_WH->setIcon(QIcon(QLatin1String(":/images/24x24/widen_h.png")));
    mActionSetUIOptCut_NW = setAction("폭줄이기", SIGNAL(triggered()), m_pDocument->m_SpriteTableWidget, SLOT(setOptCut_NW()));
    mActionSetUIOptCut_NW->setIcon(QIcon(QLatin1String(":/images/24x24/narrow_w.png")));
    mActionSetUIOptCut_NH = setAction("높이줄이기", SIGNAL(triggered()), m_pDocument->m_SpriteTableWidget, SLOT(setOptCut_NH()));
    mActionSetUIOptCut_NH->setIcon(QIcon(QLatin1String(":/images/24x24/narrow_h.png")));
    mActionAddShadowCell = setAction("그림자 추가", SIGNAL(triggered()), this, SLOT(addShadowCell()));
    mActionSetUIOptWider = setAction("모두늘이기/되돌리기", SIGNAL(triggered()), m_pDocument->m_SpriteTableWidget, SLOT(setOptCutWider()));
    mActionSetUIOptWider->setIcon(QIcon(QLatin1String(":/images/24x24/widen.png")));

    mActionSpriteListRefine = setAction("스프라이트정리", SIGNAL(triggered()), m_pDocument->m_SpriteTableWidget, SLOT(spriteListRefine()));
    // mActionSpriteListRefine->setIcon(QIcon(QLatin1String(":/images/24x24/widen.png")));

    mActionAddEmptyCell = setAction("빈셀 추가", SIGNAL(triggered()), this, SLOT(addEmptyCell()));
    mActionDeleteSprite = setAction("스프라이트 제거", SIGNAL(triggered()), this, SLOT(removeSprite()));
    mActionDeleteSprite->setIcon(QIcon(QLatin1String(":/images/16x16/edit-delete.png")));
    mActionAddEmptySprite = setAction("빈스프라이트 추가", SIGNAL(triggered()), m_pDocument->m_pSrcFigure, SLOT(AddSprite()));
    mActionAddEmptySprite->setIcon(QIcon(QLatin1String(":/images/16x16/empty.png")));
    mActionMoveSpriteUp = setAction("위로", SIGNAL(triggered()), m_pDocument->m_SpriteTableWidget, SLOT(moveItemUp()));
    mActionMoveSpriteUp->setIcon(QIcon(QLatin1String(":/images/16x16/go-up.png")));
    mActionMoveSpriteDown = setAction("아래로", SIGNAL(triggered()), m_pDocument->m_SpriteTableWidget, SLOT(moveItemDown()));
    mActionMoveSpriteDown->setIcon(QIcon(QLatin1String(":/images/16x16/go-down.png")));
//===================================================================
    // 애니메이션
    mActionMoveAniUp = setAction("위로", SIGNAL(triggered()), m_pDocument->m_AnimaionTableWidget, SLOT(moveItemUp()));
    mActionMoveAniUp->setIcon(QIcon(QLatin1String(":/images/16x16/go-up.png")));
    mActionMoveAniDown = setAction("아래로", SIGNAL(triggered()), m_pDocument->m_AnimaionTableWidget, SLOT(moveItemDown()));
    mActionMoveAniDown->setIcon(QIcon(QLatin1String(":/images/16x16/go-down.png")));
    mActionCopyAni = setAction("복사", SIGNAL(triggered()), m_pDocument->m_AnimaionTableWidget, SLOT(copyAnimation()));
    mActionCopyAni->setIcon(QIcon(QLatin1String(":/images/16x16/edit-copy.png")));
    mActionDeleteAni = setAction("삭제", SIGNAL(triggered()), m_pDocument->m_AnimaionTableWidget, SLOT(deleteAnimation()));
    mActionDeleteAni->setIcon(QIcon(QLatin1String(":/images/16x16/edit-delete.png")));
    mActionSetAniName = setAction("애니메이션이름 바꾸기(&N)",SIGNAL(triggered()), m_pDocument->m_AnimaionTableWidget, SLOT(setName()));
    // 신
    mActionCopyScene = setAction("복사", SIGNAL(triggered()), m_pDocument->m_SceneTableWidget, SLOT(copyCellList()));
    mActionCopyScene->setIcon(QIcon(QLatin1String(":/images/16x16/edit-copy.png")));
    mActionDeleteScene = setAction("삭제", SIGNAL(triggered()), m_pDocument->m_SceneTableWidget, SLOT(deleteCellList()));
    mActionDeleteScene->setIcon(QIcon(QLatin1String(":/images/16x16/edit-delete.png")));
    mActionMoveSceneUp = setAction("위로", SIGNAL(triggered()), m_pDocument->m_SceneTableWidget, SLOT(moveItemUp()));
    mActionMoveSceneUp->setIcon(QIcon(QLatin1String(":/images/16x16/go-up.png")));
    mActionMoveSceneDown = setAction("아래로", SIGNAL(triggered()), m_pDocument->m_SceneTableWidget, SLOT(moveItemDown()));
    mActionMoveSceneDown->setIcon(QIcon(QLatin1String(":/images/16x16/go-down.png")));
    mActionSetSceneName = setAction("신이름 바꾸기(&N)",SIGNAL(triggered()), m_pDocument->m_SceneTableWidget, SLOT(setName()));
    // 셀
    mActionMoveLayerUp = setAction("위로", SIGNAL(triggered()), m_pDocument->m_CellTableWidget, SLOT(moveItemUp()));
    mActionMoveLayerUp->setIcon(QIcon(QLatin1String(":/images/16x16/go-up.png")));
    mActionMoveLayerUp->setShortcut(tr("Ctrl+Shift+Up"));
    mActionMoveLayerDown = setAction("아래로", SIGNAL(triggered()), m_pDocument->m_CellTableWidget, SLOT(moveItemDown()));
    mActionMoveLayerDown->setShortcut(tr("Ctrl+Shift+Down"));
    mActionMoveLayerDown->setIcon(QIcon(QLatin1String(":/images/16x16/go-down.png")));
    mActionCopyCell = setAction("복사(&C)", SIGNAL(triggered()), m_pDocument->m_CellTableWidget, SLOT(copyCellItem()));
    mActionCopyCell->setIcon(QIcon(QLatin1String(":/images/16x16/edit-copy.png")));
    mActionDeleteCell = setAction("삭제(&D)", SIGNAL(triggered()), m_pDocument->m_CellTableWidget, SLOT(deleteCellItem()));
    mActionDeleteCell->setIcon(QIcon(QLatin1String(":/images/16x16/edit-delete.png")));
    mActionSetCellName = setAction("셀 텍스트(&N)",SIGNAL(triggered()), m_pDocument->m_CellTableWidget, SLOT(setName()));

    mActionExchangeSprite = setAction("스프라이트교체",SIGNAL(triggered()), m_pDocument->m_pSrcFigure, SLOT(exchangeSprite()));
    mActionClearColision = setAction("영역제거",SIGNAL(triggered()), m_pDocument->m_SpriteUnitFigure, SLOT(clearColision()));

    //    localeStr = codec->toUnicode("셀렉션 변경");
//    mActionChangeSelection = new QAction(this);
    connect(m_pDocument->m_SceneTableWidget, SIGNAL(changeSelectRow(int)),m_pDocument->m_SceneTableWidget, SLOT(changeSelection(int)));
//    mActionChangeSelection->setText(localeStr);
//    mActionChangeSelection->setEnabled(true);
    connect(m_pDocument->m_AnimaionTableWidget, SIGNAL(changeSelectRow(int)),m_pDocument->m_AnimaionTableWidget, SLOT(changeSelection(int)));

}

JistDocumentHandler::~JistDocumentHandler()
{
    m_pInstance = 0;
}

void JistDocumentHandler::setDocument(JistDocument *document)
{
    m_pDocument = document;
}

void JistDocumentHandler::addAnimation()
{
    if(m_pDocument)
        m_pDocument->addAnimation( QLatin1String("Animation"), false);
}

void JistDocumentHandler::addScene()
{
    if(m_pDocument)
        m_pDocument->addScene(false);
}
void JistDocumentHandler::addShadowCell()
{
    //int index = currentIndex().row();
    JistTableView *pAniTbl = m_pDocument->m_AnimaionTableWidget;
    JistTableView *pSceneTbl = m_pDocument->m_SceneTableWidget;
    JistTableView *pCellTbl = m_pDocument->m_CellTableWidget;
    JistCommonModel* aniModel = (JistCommonModel*)(pAniTbl->model());

    for(int aniIdx = 0; aniIdx < aniModel->m_pList->count(); aniIdx++){
        pAniTbl->selectRow(aniIdx);
        JistCommonModel* sceneModel = (JistCommonModel*)(pSceneTbl->model());
        pSceneTbl->selectRow(0);
        JistCommonModel* cellModel = (JistCommonModel*)(pCellTbl->model());
        int iX = cellModel->m_pList->at(0).m_pIItem->m_oIndex_X;
        int iY = cellModel->m_pList->at(0).m_pIItem->m_oIndex_Y;
        for(int sceneIdx = 0; sceneIdx < sceneModel->m_pList->count(); sceneIdx++){
            pSceneTbl->selectRow(sceneIdx);
            //JistCommonModel* cellModel = (JistCommonModel*)(pCellTbl->model());
            m_pDocument->addShadowCell(iX, iY);
        }
    }
}

void JistDocumentHandler::addCell()
{
    if(m_pDocument)
        m_pDocument->addCell();
}

void JistDocumentHandler::addEmptyCell()
{
    if(m_pDocument)
        m_pDocument->addCell(true);
}

void JistDocumentHandler::removeSprite()
{
    int imglIndex = m_pDocument->m_ImageTableWidget->currentIndex().row();
    int selIndex = m_pDocument->m_SpriteTableWidget->currentIndex().row();

    Tiled::Internal::DocumentManager *docMan =  Tiled::Internal::DocumentManager::instance();
    int index = selIndex;
    int groupCnt = 0;
    Tiled::Internal::MapDocument *mapDoc = docMan->currentDocument();
    QList<Tiled::ObjectGroup*> groups = mapDoc->map()->objectGroups();
    QUndoStack *undoStack = mapDoc->undoStack();
    //undoStack->beginMacro(tr("Remove %n Object(s)", "", objects.size()));
    undoStack->beginMacro(tr("Remove  Object(s)"));
    while (groupCnt < groups.count()){
        Tiled::ObjectGroup* tempGroup = groups.at(groupCnt++);
        int objCnt = 0;
        //while (xml.readNextStartElement()) {
        //while (objCnt < tempGroup->objects().count())
        foreach (Tiled::MapObject *object, tempGroup->objects())
        {
            // 오브젝트 로드
            //Tiled::MapObject *object = tempGroup->objects()[objCnt];

            if (object->jistCell()) {
                const unsigned iid = object->jistCell()->m_iImgIndex; // 실제 인덱스
                const unsigned sid = object->jistCell()->m_iSpriteIndex; // 실제 인덱스
                if(iid == imglIndex && sid == index){
                    qDebug("deleteSprite %d", objCnt);
                    object->setCell(NULL);
                    undoStack->push(new Tiled::Internal::RemoveMapObject(mapDoc, object));
                }else if(iid == imglIndex && sid > index){ // 지우는 스프라이트인덱스보다 인덱스가 크면 임시 스프라이트인덱스 1 감소
                    object->SetImgIndex(object->GetSpriteIndex()-1); // 임시인덱스 관리
                }
            }
            objCnt++;
        }
    }
    // 스프라이트 인덱스 재설정!!!!!!!!!!!!!!!!!!!!!!!!!!
    for(int k = 0; k < m_pDocument->m_SpriteData[imglIndex].count(); k++){
        JistCommonData &currentSpriteData = m_pDocument->m_SpriteData[imglIndex][k];
        if(currentSpriteData.GetSpriteIndex() > selIndex) // 지워진 인덱스의 하위인덱스만 1감소
            currentSpriteData.SetSpriteIndex(currentSpriteData.GetSpriteIndex() - 1);
    }

    undoStack->endMacro();
    Tiled::Internal::MapScene *curScene = docMan->currentMapScene();
    // 이미지 인덱스 재설정
    groupCnt = 0;
//    while (groupCnt < groups.count()){
//        Tiled::ObjectGroup* tempGroup = groups.at(groupCnt++);
//        int objCnt = 0;
//        foreach (Tiled::MapObject *object, tempGroup->objects())
//        {
//            if (object->jistCell()) {
//                const unsigned iid = object->jistCell()->m_iImgIndex;
//                const unsigned sid = object->GetSpriteIndex();
//                if(iid == imglIndex && sid > index){ // 임시 인덱스로 재설정
//                    object->jistCell()->m_iSpriteIndex = sid;
//                }
//            }
//            objCnt++;
//        }
//    }
    curScene->syncAllObjectItems();

    if(m_pDocument && selIndex >= 0)
    {
        JistCommonModel *dataModel = (JistCommonModel*)(m_pDocument->m_SpriteTableWidget->model());
        //JistCommonData srcData = dataModel->m_pList->at(selIndex);
        JistCommonData &srcData = m_pDocument->m_SpriteData[m_pDocument->m_iCurrentSpriteDataIndex][selIndex];
        QImage *img = &srcData.m_img;
        dataModel->removeRow(selIndex);
        int nIndex = selIndex;
        if (selIndex == dataModel->rowCount())
            nIndex = selIndex - 1;
        m_pDocument->m_SpriteTableWidget->refineView(nIndex);
        // 리스트뷰및 신뷰 갱신
        for(int a = 0; a < m_pDocument->m_CellData.count(); a++){
            for(int s = 0; s < m_pDocument->m_CellData[a].count(); s++){
                for(int c = 0; c < m_pDocument->m_CellData[a][s].count(); c++){
                    int imgId = (m_pDocument->m_CellData[a][s][c]).m_iImgIndex;
                    int spriteId = (m_pDocument->m_CellData[a][s][c]).m_iSpriteIndex;
                    // 지워진 스프라이트를 참조하는 셀 정리
                    if((m_pDocument->m_CellData[a][s][c]).m_pIItem->m_SrcImage == img)
                    {
                        (m_pDocument->m_CellData[a][s][c]).m_pIItem->m_SrcImage = NULL;
                        (m_pDocument->m_CellData[a][s][c]).m_img = QImage();
                    }
                    // 지워짐으로 변경되는 셀정리
                    // 스프라이트 인덱스가 지워진 것보다 큰 것이면 1씩 차감
                    if(imglIndex == imgId && selIndex < spriteId)
                        (m_pDocument->m_CellData[a][s][c]).m_iSpriteIndex -= 1;
                    if(imgId != -1 && imgId < m_pDocument->m_SpriteData.count() && spriteId < m_pDocument->m_SpriteData[imgId].count()){
                        //(m_pDocument->m_CellData[a][s][c]).m_img = m_pDocument->m_SpriteData[imgId][spriteId].m_img;
                    }else{
                        (m_pDocument->m_CellData[a][s][c]).m_img = g_EmptyImage;//QImage();
                        (m_pDocument->m_CellData[a][s][c]).m_pIItem->m_SrcImage = NULL;
                    }
                    // 신뷰의 갱신
                    qreal r = (m_pDocument->m_CellData[a][s][c]).m_pIItem->scale();
                    QSizeF sc = (m_pDocument->m_CellData[a][s][c]).m_pIItem->scaleXY();
                    (m_pDocument->m_CellData[a][s][c]).m_pIItem->init();
                    (m_pDocument->m_CellData[a][s][c]).m_pIItem->setScaleX(sc.width());
                    (m_pDocument->m_CellData[a][s][c]).m_pIItem->setScaleY(sc.height());
                    (m_pDocument->m_CellData[a][s][c]).m_pIItem->recalculateResult();

                }
            }
        }
        if(m_pDocument->m_CellTableWidget)
            m_pDocument->m_CellTableWidget->refineViewNoUndo(m_pDocument->m_CellTableWidget->currentIndex().row());
        if(m_pDocument->m_pSceneFrameFigure)
            m_pDocument->m_pSceneFrameFigure->m_canvas.update();
    }
}


void JistDocumentHandler::removeSprite_Fast()
{
    int imglIndex = m_pDocument->m_ImageTableWidget->currentIndex().row();
    int selIndex = m_pDocument->m_SpriteTableWidget->currentIndex().row();

    if(m_pDocument && selIndex >= 0)
    {
        JistCommonModel *dataModel = (JistCommonModel*)(m_pDocument->m_SpriteTableWidget->model());
        //JistCommonData srcData = dataModel->m_pList->at(selIndex);
        JistCommonData &srcData = m_pDocument->m_SpriteData[m_pDocument->m_iCurrentSpriteDataIndex][selIndex];
        QImage *img = &srcData.m_img;
        dataModel->removeRow(selIndex);
        int nIndex = selIndex;
        if (selIndex == dataModel->rowCount())
            nIndex = selIndex - 1;
        m_pDocument->m_SpriteTableWidget->refineView(nIndex);
        // 리스트뷰및 신뷰 갱신
        for(int a = 0; a < m_pDocument->m_CellData.count(); a++){
            for(int s = 0; s < m_pDocument->m_CellData[a].count(); s++){
                for(int c = 0; c < m_pDocument->m_CellData[a][s].count(); c++){
                    int imgId = (m_pDocument->m_CellData[a][s][c]).m_iImgIndex;
                    int spriteId = (m_pDocument->m_CellData[a][s][c]).m_iSpriteIndex;
                    // 지워진 스프라이트를 참조하는 셀 정리
                    if((m_pDocument->m_CellData[a][s][c]).m_pIItem->m_SrcImage == img)
                    {
                        (m_pDocument->m_CellData[a][s][c]).m_pIItem->m_SrcImage = NULL;
                        (m_pDocument->m_CellData[a][s][c]).m_img = QImage();
                    }
                    // 지워짐으로 변경되는 셀정리
                    // 스프라이트 인덱스가 지워진 것보다 큰 것이면 1씩 차감
                    if(imglIndex == imgId && selIndex < spriteId)
                        (m_pDocument->m_CellData[a][s][c]).m_iSpriteIndex -= 1;
                    if(imgId != -1 && imgId < m_pDocument->m_SpriteData.count() && spriteId < m_pDocument->m_SpriteData[imgId].count()){
                        //(m_pDocument->m_CellData[a][s][c]).m_img = m_pDocument->m_SpriteData[imgId][spriteId].m_img;
                    }else{
                        (m_pDocument->m_CellData[a][s][c]).m_img = g_EmptyImage;//QImage();
                        (m_pDocument->m_CellData[a][s][c]).m_pIItem->m_SrcImage = NULL;
                    }
                }
            }
        }
    }
}

QAction* JistDocumentHandler::setAction(const char *in, const char *asignal,
                                    const QObject * receiver, const char * method)
{
    //QTextCodec * codec = QTextCodec::codecForName("EUC-KR");
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    QString localeStr = codec->toUnicode(in);
    QAction *action = new QAction(this);
    connect(action, asignal,receiver, method);
    action->setText(localeStr);
    action->setEnabled(true);
    return action;
}

void JistDocumentHandler::SyncAllObject()
{
    Tiled::Internal::DocumentManager *docMan =  Tiled::Internal::DocumentManager::instance();
    Tiled::Internal::MapScene *curScene = docMan->currentMapScene();
    curScene->syncAllObjectItems();
    curScene->update();

    docMan->currentDocument()->emitColisionChanged();
}
